最近为了提高日志入库的速度,把入库的代码改成并发的。发现部分日志入库的时候mysql报错:

Error 1213: Deadlock found when trying to get lock; try restarting transaction.

字面意思可见是有死锁了。

出现死锁,首先查询状态日志,mysql执行:

SHOW ENGINE INNODB STATUS

查询LATEST DETECTED DEADLOCK标签下的日志,可见最近一次发生死锁的语句。再加上对比正常执行的sql语句,问题定位在使用replace into上。

innodb是行级锁,而我是并发且批量去使用replace into去更新表,很容易造成同时两条语句去更新一行数据。replace的时候会给要更新的行加上排他锁(X锁),这就是造成死锁的原因。(有唯一索引的表在insert的时候,如果发生了唯一索引冲突,会加上读锁(S锁),理论上在并发处理的时候不会死锁?待证实)。


Cedrus
363 声望9 粉丝

不积跬步,无以致千里